import { YmCssMotion } from '@/YmCssMotion';
import classNames from 'classnames';
import { useContext, useLayoutEffect, useState } from 'react';
import TreeContext from './Context/TreeContext';
import { MOTION_KEY } from './NodeList';
import TreeNode from './TreeNode';
import type { MotionTreeNodeProps } from './interface';
import { getTreeNodeProps } from './utils/treeUtils';

function MotionTreeNode(props: MotionTreeNodeProps) {
  const { prefixCls, keyEntities } = useContext(TreeContext)!;
  const [visible, setVisible] = useState<boolean>(true);
  const {
    eventKey,
    title,
    isStart,
    isEnd,
    data,
    motionType,
    motion,
    motionNodes,
    onMotionEnd,
    treeNodeRequiredProps,
    expandedKeys,
    loadingKeys,
    loadedKeys,
    checkedKeys,
    halfCheckedKeys,
    selectedKeys,
  } = props;

  const targetVisible = motionNodes && motionType !== 'hide';

  //关闭的时候
  useLayoutEffect(() => {
    if (motionNodes) {
      if (targetVisible !== visible) {
        //关闭
        setVisible(!!targetVisible);
      }
    }
  }, [motionNodes]);

  //动画执行完毕
  const handleVisibleChange = (newVisible: boolean) => {
    if (targetVisible === newVisible) {
      onMotionEnd();
    }
  };

  if (eventKey === MOTION_KEY) {
    if (motionNodes?.length) {
      return (
        <YmCssMotion
          visible={visible}
          motionAppear={motionType === 'show'}
          motionEnter={false}
          onVisibleChanged={handleVisibleChange}
          {...motion}
        >
          {({ className: motionClassName, style: motionStyle }, motionRef) => {
            return (
              <div
                ref={motionRef as any}
                className={classNames(
                  `${prefixCls}-treenode-motion`,
                  motionClassName,
                )}
                style={motionStyle}
              >
                {motionNodes.map((treeNode) => {
                  const { key, isStart, isEnd, title, data } = treeNode;
                  const treeNodeRequiredPropsInMotion = getTreeNodeProps(
                    key,
                    {
                      expandedKeys,
                      loadingKeys,
                      loadedKeys,
                      checkedKeys,
                      halfCheckedKeys,
                      selectedKeys,
                    },
                    keyEntities,
                  );
                  return (
                    <TreeNode
                      key={key}
                      eventKey={eventKey}
                      title={title}
                      isStart={isStart}
                      isEnd={isEnd}
                      data={data}
                      {...treeNodeRequiredPropsInMotion}
                    />
                  );
                })}
              </div>
            );
          }}
        </YmCssMotion>
      );
    } else {
      return null;
    }
  }

  return (
    <TreeNode
      eventKey={eventKey}
      title={title}
      isStart={isStart}
      isEnd={isEnd}
      data={data}
      {...treeNodeRequiredProps}
    />
  );
}

export default MotionTreeNode;
